######################################################################################
# Sample ruby applications using the Aastra XML API Classes with GD extensions
# Aastra SIP Phones Firmware 2.3.0 or better
# Copyright Aastra Telecom 2008
#
# Ruby adaptation by Carlton O'Riley
#
# /aastra_gd_sample/{type} where type is the object to display
#	  type=aclock		Analog clock using server local time
#	  type=dclock		Digital clock using server local time
#	  type=font		Different font
#	  type=countdown	Countdown from 0009 to 0000
#	  type=chinese1		Chinese display 1
#	  type=chinese2		Chinese display 2
#	  type=arabic		Arabic display
#	  type=russian		Russian display
#	  type=yahtzee		Yathzee display simulation
#
# If type is not set, the list of all the XML applications is displayed
# i.e. http://railsserver:3000/aastra_gd_sample
#
# The following fonts must be located in the default font path or made available from 
# this script. (for rails this is RAILS_ROOT/fonts)
#   - times.ttf
#   - arialuni.ttf
#   - Ni7seg.ttf
#
######################################################################################

class AastraGdSampleController < ApplicationController
  require 'AastraIPPhoneGDImage.rb'
  require 'AastraIPPhoneImageScreen.rb'
  require 'AastraIPPhoneTextMenu.rb'
  require 'AastraIPPhoneTextScreen.rb'

  before_filter :check_aastra
  after_filter :set_headers

  def check_aastra
    return if aastra_test_phone_version('2.3.0', 0) != 0
    return if not aastra_test_phone_model(['Aastra55i', 'Aastra57i', 'Aastra57iCT'], true, 0)
    @userHeader = aastra_decode_HTTP_header
  end

  def set_headers
    if not @aastraObj.nil? then
      headers['Content-Type'] = "text/xml; charset=ISO-8859-1"
      headers['Refresh'] = "#{@aastraObj.getRefreshTimeout}; url=#{@aastraObj.getRefreshURL}" if @aastraObj.getRefreshTimeout != 0 and not @aastraObj.getRefreshURL.nil?
      headers['Content-Length'] = @xml.length
    end
  end

  def aastra_output(aastraObj=nil)
    @aastraObj = aastraObj
    if not @aastraObj.nil?
      @xml = '<?xml version="1.0" encoding="ISO-8859-1"?>'+"\n"
      @xml += @aastraObj.render
      puts "SENDING:\n#{@xml}"
    end
    render :action => "aastra_output"
  end

  def aastra_decode_HTTP_header
    user_agent = request.headers['HTTP_USER_AGENT']
    if not user_agent.index(/Aastra/i).nil? then
      value = user_agent.split(/ MAC:/)
      fin = value[1].split(/ /)
      value[1] = fin[0].sub(/\-/,"")
      value[2] = fin[1].sub(/V:/,"")
    else
      value = ["MSIE", "NA", "NA"]
    end
    return {'model' => value[0], 'mac' => value[1], 'firmware' => value[2]}
  end

  def aastra_test_phone_model(models, check, type)
    userHeader = aastra_decode_HTTP_header
    return true if models.include?(userHeader['model']) == check
    if type == 0 then
       aastraObj = AastraIPPhoneTextScreen.new
       aastraObj.setTitle("Phone not supported")
       aastraObj.setText("This XML application is not supported by your phone.")
       aastra_output aastraObj
    end
    return false
  end

  def aastra_test_phone_version(version, type)
    ret = 0
    # Start with the HTTP header
    userHeader = aastra_decode_HTTP_header
    # Must be an Aastra
    if not userHeader['model'].index(/Aastra/i).nil? then
      # Retrive firmware version
      piece = userHeader['firmware'].split(/\./)
      count = piece.size-1
      phone_version = piece[0].to_i*100
      phone_version += piece[1].to_i*10 if count > 1
      phone_version += piece[2].to_i if count > 2
      piece = version.split(/\./)
      count = piece.size-1
      test_version = piece[0].to_i*100
      test_version += piece[1].to_i*10 if count > 1
      test_version += piece[2].to_i if count > 2

      # Compare to passed version
      if test_version > phone_version then
        ret = 2
        if type == 0 then
          aastraObj = AastraIPPhoneTextScreen.new
          aastraObj.setTitle("Firmware not compatible")
          aastraObj.setText("This XML application needs firmware version #{version} or higher.")
          aastra_output aastraObj
        end
      end
    else
      ret = 1
      if type == 0 then
        @xml = "This XML application works better when using an Aastra IP phone, not a web browser.<p>See <a href=\"http://www.aastratelecom.com/cps/rde/xchg/SID-3D8CCB73-C78FC1E1/03/hs.xsl/23485.htm\">here</a> for instructions and information.<p>Copyright Aastra Telecom 2008."
        render :action => "aastra_output"
      end
    end
    return ret
  end

  def analogClock
    img = GD::Image.new(144, 40)
    white = img.colorAllocate(0, 0, 0)
    black = img.colorAllocate(255, 255, 255)
    white *= -1
    black *= -1
    imSize = 39
    clockSize = imSize
    time = Time.now
    hour = time.hour
    minutes = time.min
    seconds = time.sec
    
    hour -= 12 if hour >= 12
    hourDegrees = hour*30
    hourDegrees += minutes/2
    minDegrees = minutes*6

    # The coordinate system starts at 3:00
    hourDegrees -= 90
    hourDegrees += 360 if hourDegrees < 0
    minDegrees -= 90
    minDegrees += 360 if minDegrees < 0

    # Convert to radians
    hourRadians = hourDegrees / 57.295779513082
    minRadians = minDegrees / 57.295779513082

    # draw the clock circle
    img.arc(imSize/2, imSize/2, clockSize, clockSize, 0, 359, black)
    img.arc(imSize/2, imSize/2, clockSize-1, clockSize-1, 0, 359, black)

    # draw the hour hand
    hourHandLen=(clockSize / 2) * 0.6
    x2=imSize/2 + (hourHandLen * Math.cos(hourRadians))
    y2=imSize/2 + (hourHandLen * Math.sin(hourRadians))
    img.line(imSize/2, imSize/2, x2, y2, black)

    # draw the minute hand
    minHandLen=(clockSize / 2) * 0.9
    x2=imSize/2 + (minHandLen * Math.cos(minRadians))
    y2=imSize/2 + (minHandLen * Math.sin(minRadians))
    img.line(imSize/2, imSize/2, x2, y2, black)

    return img
  end

  def index
    aastraObj = AastraIPPhoneTextMenu.new
    aastraObj.setTitle('Graphics Apps Demo')
    aastraObj.addEntry('Digital Clock', request.protocol+request.host_with_port+'/'+controller_name+'/dclock')
    aastraObj.addEntry('Analog Clock', request.protocol+request.host_with_port+'/'+controller_name+'/aclock')
    aastraObj.addEntry('Different Font', request.protocol+request.host_with_port+'/'+controller_name+'/font')
    aastraObj.addEntry('Countdown', request.protocol+request.host_with_port+'/'+controller_name+'/countdown')
    aastraObj.addEntry('Unicode Chinese', request.protocol+request.host_with_port+'/'+controller_name+'/chinese')
    aastraObj.addEntry('Unicode Arabic', request.protocol+request.host_with_port+'/'+controller_name+'/arabic')
    aastraObj.addEntry('Unicode Russian', request.protocol+request.host_with_port+'/'+controller_name+'/russian')
    aastraObj.addEntry('Yahtzee', request.protocol+request.host_with_port+'/'+controller_name+'/yahtzee')
    aastraObj.natsortByName
    aastra_output aastraObj
  end

  def dclock
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    time = Time.now.strftime("%H:%M")
    img.drawttftext(30, 0, 10, 39, time, 1, 'Ni7seg.ttf')
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end

  def aclock
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    time = Time.now.strftime("%H:%M")
    img.setGDImage(analogClock)
    img.drawttftext(25, 0, 42, 32, " #{time}", 1, 'times.ttf')
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end

  def font
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    img.drawttftext(39, 0, 1, 39, "Hello!", 1, 'times.ttf')
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end

  def countdown
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    if params[:id].nil? then
      count = 9
    else
      count = params[:id].to_i
    end
    if count > -1 then
      text = "000" + count.to_s
      count -= 1
      aastraObj.setRefresh(1, request.protocol+request.host_with_port+'/'+controller_name+'/countdown/'+count.to_s)
      img.drawttftext(35, 0, 5, 39, text, 1, 'Ni7seg.ttf')
    else
      img.drawttftext(20, 0, 10, 39, 'IGNITION', 1, 'Ni7seg.ttf')
    end
    aastraObj.setDestroyOnExit
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end

  def chinese
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    utf8text = "&#36895;&#23416;&#31777;&#21270;&#23383;"
    img.drawttftext(20, 0, 5, 35, utf8text, 1, 'arialuni.ttf')
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end

  def arabic
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    utf8text = "&#1605;&#1575;&#1604;&#1587;"
    img.drawttftext(20, 0, 30, 30, utf8text, 1, 'arialuni.ttf')
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end

  def russian
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    utf8text = "&#1044;&#1086; &#1089;&#1074;&#1080;&#1076;&#1072;&#1085;&#1080;&#1103;"
    img.drawttftext(17, 0, 10, 30, utf8text, 1, 'arialuni.ttf')
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end

  def yahtzee
    img = AastraIPPhoneGDImage.new
    aastraObj = AastraIPPhoneImageScreen.new
    val = 1 + rand(6)
    for i in 1..6
      img.rectangle(1+(i-1)*26+13,1,15+(i-1)*26+13, 15, 1)
      if val==2 or val==4 or val==5 or val==6 then
        img.rectangle(3+(i-1)*26+13,3,5+(i-1)*26+13,5,1,true)
        img.rectangle(11+(i-1)*26+13,11,13+(i-1)*26+13,13,1,true)
      end
      if val==6 then
        img.rectangle(3+(i-1)*26+13,7,5+(i-1)*26+13,9,1,true)
        img.rectangle(11+(i-1)*26+13,7,13+(i-1)*26+13,9,1,true)
      end
      if val==3 or val==4 or val==5 or val==6  then
        img.rectangle(3+(i-1)*26+13,11,5+(i-1)*26+13,13,1,true)
        img.rectangle(11+(i-1)*26+13,3,13+(i-1)*26+13,5,1,true)
      end
      if val==1 or val==3 or val==5 then
        img.rectangle(7+(i-1)*26+13,7,9+(i-1)*26+13,9,1,true)
      end
    end
    img.rectangle(0, 20, 144, 40, 1, true)
    img.drawttftext(16, 0, 18, 39, 'Yahtzee!', 0, 'Ni7seg.ttf')
    aastraObj.setGDImage(img)
    aastra_output aastraObj
  end
end
